<?php
/**
 * 캐쉬 관리 - Filememcache
 *
 * @package util
 * @subpackage cache
 *
 * @author jylee3@simplexi.com
 * @version 1.0
 */
class utilCacheManageFilememcache extends utilCacheManageAbstract implements utilCacheManageInterface
{
    /**
     * Memcache 드라이버 객체
     * @var Memcache
     */
    private static $Memcache;

    /**
     * 캐쉬 설정   객체
     * @var utilCacheConfig
     */
    protected $cacheConfig;

    public function __construct(utilCacheConfig $cacheConfig)
    {
        $this->cacheConfig = $cacheConfig;

        if (!self::$Memcache) {

            $sHost = $this->cacheConfig->sMemcacheHost;
            $sPort = $this->cacheConfig->sMemcachePort;

            self::$Memcache = new Memcache();

            $isConn = self::$Memcache->connect($sHost, $sPort);

            if ($isConn === false) {
                throw new Exception('utilCache - can not connect to memcache host => ' . $sHost . ' : ' . $sPort);
            }

        }
    }

    /**
     * 캐쉬 관리 설정
     *
     * @param    String    $sClassName
     * @param    String    $sKey
     *
     * @return    Mixed
     */
    public function setCacheManage($sClassName, $sKey)
    {
        $Memcache = self::$Memcache;

        if ($Memcache) {
            $iExpireTime = time();

            /**
             * 전체 캐쉬 갱신시간 변경.(단, 해당 값이 없을경우)
             */
            $mMemcacheCacheExpired = $Memcache->get('CACHE_' . $this->cacheConfig->sCacheName);

            if ($mMemcacheCacheExpired == false) {
                $Memcache->set('CACHE_' . $this->cacheConfig->sCacheName, $iExpireTime);
            }

            /**
             * 지정된 클래스 갱신시간 변경
             */
            $Memcache->set('CACHE_' . $this->cacheConfig->sCacheName . '_' . $sClassName, $iExpireTime);

            return true;
        } else {
            return false;
        }
    }

    /**
     * 캐쉬 만료여부 반환
     * (false 가 갱신한다는 의미)
     *
     * @param    String    $sClassName
     * @param    String    $sKey
     *
     * @return    Boolean
     */
    public function isCacheExpired($sClassName, $sKey)
    {
        $Memcache = self::$Memcache;

        $mMemcacheCacheExpire = false;
        $mMemcacheClassExpire = false;

        if ($Memcache) {
            $mMemcacheExpireTime = $Memcache->get(array('CACHE_' . $this->cacheConfig->sCacheName, 'CACHE_' . $this->cacheConfig->sCacheName . '_' . $sClassName));

            if ($mMemcacheExpireTime) {
                $mMemcacheCacheExpire = $mMemcacheExpireTime['CACHE_' . $this->cacheConfig->sCacheName];
                $mMemcacheClassExpire = $mMemcacheExpireTime['CACHE_' . $this->cacheConfig->sCacheName . '_' . $sClassName];
            }
        }

        if ($mMemcacheCacheExpire==false || $mMemcacheClassExpire==false)    return false;

        $sCacheDataFile = $this->getCacheDataFile($sClassName, $sKey);

        if (!is_file($sCacheDataFile)) {
            return false;
        }

        $iVaildTime = time() - $this->cacheConfig->iExpireTime;

        $iFileModifyTime = filemtime($sCacheDataFile);

        if (!is_numeric($mMemcacheCacheExpire) || $mMemcacheCacheExpire>$iFileModifyTime) {
            return false;
        }

        if (!is_numeric($mMemcacheClassExpire) || $mMemcacheClassExpire>$iFileModifyTime) {
            return false;
        }

        if (!is_numeric($iFileModifyTime) || $iFileModifyTime<$iVaildTime) {
            return false;
        }

        return true;
    }

    /**
     * 캐쉬 지정 클래스 초기화
     *
     * @param    String    $sClassName
     *
     * @return Boolean
     */
    public function setClear($sClassName)
    {
        $Memcache = self::$Memcache;

        if ($Memcache) {
            return $Memcache->delete('CACHE_' . $this->cacheConfig->sCacheName . '_' . $sClassName);
        } else {
            return false;
        }
    }

    /**
     * 캐쉬 전체 초기화
     *
     * @return Boolean
     */
    public function setClearAll()
    {
        $Memcache = self::$Memcache;

        if ($Memcache) {
            return $Memcache->delete('CACHE_' . $this->cacheConfig->sCacheName);
        } else {
            return false;
        }
    }

    /**
     * 캐쉬 데이터 파일경로 반환
     *
     * @param    String    $sClassName
     * @param    String    $sFileName
     *
     * @return    String
     */
    protected function getCacheDataFile($sClassName, $sFileName)
    {
        $sCacheName = $this->cacheConfig->sCacheName;
        $iDirectoryVariance = $this->cacheConfig->iDirectoryVariance;

        $sCacheDataPath = $this->cacheConfig->sDefaultPath . DS
            . utilCacheWriterFile::CACHE_DIR . DS
            . $sCacheName . DS . $sClassName;

        if (!empty($sFileName)) {
            if ($iDirectoryVariance>0) {
                $aDirectoryVariance = array();

                for ($i=0; $i<$iDirectoryVariance; $i++) {
                    $aDirectoryVariance[] = substr($sFileName, $i, 1);
                }

                $sCacheDataPath = $sCacheDataPath . DS . implode(DS, $aDirectoryVariance);
            }
        }

        return $sCacheDataPath . DS. $sFileName . utilCacheWriterFile::CACHE_EXT . '.' . strtolower($this->cacheConfig->sWriterParser);
    }
}